home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH7 / SRC / BOXES2.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1996-05-01  |  17.1 KB  |  546 lines

  1. VERSION 4.00
  2. Begin VB.Form BoxesForm 
  3.    Caption         =   "Quadtree"
  4.    ClientHeight    =   3750
  5.    ClientLeft      =   2640
  6.    ClientTop       =   1545
  7.    ClientWidth     =   3150
  8.    Height          =   4440
  9.    Left            =   2580
  10.    LinkTopic       =   "Form1"
  11.    ScaleHeight     =   3750
  12.    ScaleWidth      =   3150
  13.    Top             =   915
  14.    Width           =   3270
  15.    Begin VB.HScrollBar HScrollBar 
  16.       Height          =   255
  17.       Left            =   0
  18.       TabIndex        =   2
  19.       Top             =   2880
  20.       Width           =   2895
  21.    End
  22.    Begin VB.VScrollBar VScrollBar 
  23.       Height          =   2895
  24.       Left            =   2880
  25.       TabIndex        =   1
  26.       Top             =   0
  27.       Width           =   255
  28.    End
  29.    Begin VB.PictureBox viewport 
  30.       Height          =   2880
  31.       Left            =   0
  32.       ScaleHeight     =   2820
  33.       ScaleWidth      =   2820
  34.       TabIndex        =   0
  35.       Top             =   0
  36.       Width           =   2880
  37.    End
  38.    Begin VB.Label Label1 
  39.       Alignment       =   2  'Center
  40.       Caption         =   "Boxes created"
  41.       Height          =   255
  42.       Index           =   1
  43.       Left            =   240
  44.       TabIndex        =   6
  45.       Top             =   3240
  46.       Width           =   1095
  47.    End
  48.    Begin VB.Label CreatedLabel 
  49.       BorderStyle     =   1  'Fixed Single
  50.       Height          =   255
  51.       Left            =   480
  52.       TabIndex        =   5
  53.       Top             =   3480
  54.       Width           =   615
  55.    End
  56.    Begin VB.Label BoxesLabel 
  57.       BorderStyle     =   1  'Fixed Single
  58.       Height          =   255
  59.       Left            =   1800
  60.       TabIndex        =   4
  61.       Top             =   3480
  62.       Width           =   615
  63.    End
  64.    Begin VB.Label Label1 
  65.       Alignment       =   2  'Center
  66.       Caption         =   "Boxes drawn"
  67.       Height          =   255
  68.       Index           =   0
  69.       Left            =   1560
  70.       TabIndex        =   3
  71.       Top             =   3240
  72.       Width           =   1095
  73.    End
  74.    Begin VB.Menu mnuFile 
  75.       Caption         =   "&File"
  76.       Begin VB.Menu mnuFileExit 
  77.          Caption         =   "E&xit"
  78.       End
  79.    End
  80.    Begin VB.Menu mnuScale 
  81.       Caption         =   "&Scale"
  82.       Begin VB.Menu mnuScaleZoom 
  83.          Caption         =   "&Zoom"
  84.          Shortcut        =   ^Z
  85.       End
  86.       Begin VB.Menu mnuScaleMag 
  87.          Caption         =   "Full  Scale"
  88.          Index           =   1
  89.          Shortcut        =   ^F
  90.       End
  91.       Begin VB.Menu mnuScaleMag 
  92.          Caption         =   "Magnify 1/2"
  93.          Index           =   20
  94.          Shortcut        =   ^{F2}
  95.       End
  96.       Begin VB.Menu mnuScaleMag 
  97.          Caption         =   "Magnify 1/4"
  98.          Index           =   40
  99.          Shortcut        =   ^{F4}
  100.       End
  101.    End
  102. Attribute VB_Name = "BoxesForm"
  103. Attribute VB_Creatable = False
  104. Attribute VB_Exposed = False
  105. Option Explicit
  106. Dim ThePicture As ObjPicture
  107. ' Global max and min world coordinates
  108. ' (including margins).
  109. Dim DataXmin As Single
  110. Dim DataXmax As Single
  111. Dim DataYmin As Single
  112. Dim DataYmax As Single
  113. ' Set the min and max allowed width and height.
  114. Dim DataMinWid As Single
  115. Dim DataMinHgt As Single
  116. Dim DataMaxWid As Single
  117. Dim DataMaxHgt As Single
  118. ' The aspect ratio of the viewport.
  119. Dim VAspect As Single
  120. ' Current world window bounds.
  121. Dim Wxmin As Single
  122. Dim Wxmax As Single
  123. Dim Wymin As Single
  124. Dim Wymax As Single
  125. ' Prevent change events when we are adjusting the
  126. ' scroll bars.
  127. Dim IgnoreSbarChange As Boolean
  128. ' Variables used for zooming.
  129. Dim DrawingMode As Integer
  130. Const MODE_NONE = 0
  131. Const MODE_START_ZOOM = 1
  132. Const MODE_ZOOMING = 2
  133. Dim StartX As Single
  134. Dim StartY As Single
  135. Dim LastX As Single
  136. Dim LastY As Single
  137. Dim OldMode As Integer
  138. ' The object that is highlighted.
  139. Dim highlighted As Object
  140. ' ************************************************
  141. ' End a zoom operation early. This happens if the
  142. ' user starts a zoom and the selects another menu
  143. ' item instead of doing the zoom.
  144. ' ************************************************
  145. Sub StopZoom()
  146.     If DrawingMode <> MODE_START_ZOOM Then Exit Sub
  147.     DrawingMode = MODE_NONE
  148.     Viewport.DrawMode = OldMode
  149.     Viewport.MousePointer = vbDefault
  150. End Sub
  151. ' ************************************************
  152. ' Change the level of magnification.
  153. ' ************************************************
  154. Sub SetScaleFactor(fact As Single)
  155. Dim wid As Single
  156. Dim hgt As Single
  157. Dim mid As Single
  158.     fact = 1 / fact
  159.     ' Compute the new world window size.
  160.     wid = fact * (Wxmax - Wxmin)
  161.     hgt = fact * (Wymax - Wymin)
  162.     ' Center the new world window over the old.
  163.     mid = (Wxmax + Wxmin) / 2
  164.     Wxmin = mid - wid / 2
  165.     Wxmax = mid + wid / 2
  166.     mid = (Wymax + Wymin) / 2
  167.     Wymin = mid - hgt / 2
  168.     Wymax = mid + hgt / 2
  169.     ' Set the new world window bounds.
  170.     SetWorldWindow
  171. End Sub
  172. ' ************************************************
  173. ' Adjust the world window so it is not too big,
  174. ' too small, off to one side, or of the wrong
  175. ' aspect ratio. Then map the world window to the
  176. ' viewport and force the viewport to repaint.
  177. ' ************************************************
  178. Sub SetWorldWindow()
  179. Dim wid As Single
  180. Dim hgt As Single
  181. Dim xmid As Single
  182. Dim ymid As Single
  183. Dim aspect As Single
  184.     wid = Wxmax - Wxmin
  185.     xmid = (Wxmax + Wxmin) / 2
  186.     hgt = Wymax - Wymin
  187.     ymid = (Wymax + Wymin) / 2
  188.         
  189.     ' Make sure we're not too big or too small.
  190.     If wid > DataMaxWid Then
  191.         wid = DataMaxWid
  192.     ElseIf wid < DataMinWid Then
  193.         wid = DataMinWid
  194.     End If
  195.     If hgt > DataMaxHgt Then
  196.         hgt = DataMaxHgt
  197.     ElseIf hgt < DataMinHgt Then
  198.         hgt = DataMinHgt
  199.     End If
  200.     ' Make the aspect ratio match the
  201.     ' viewport aspect ratio.
  202.     aspect = hgt / wid
  203.     If aspect > VAspect Then
  204.         ' Too tall and thin. Make it wider.
  205.         wid = hgt / VAspect
  206.     Else
  207.         ' Too short and wide. Make it taller.
  208.         hgt = wid * VAspect
  209.     End If
  210.     ' Compute the new coordinates
  211.     Wxmin = xmid - wid / 2
  212.     Wxmax = xmid + wid / 2
  213.     Wymin = ymid - hgt / 2
  214.     Wymax = ymid + hgt / 2
  215.     ' Check that we're not off to one side.
  216.     If wid > DataMaxWid Then
  217.         ' We're wider than the picture. Center.
  218.         xmid = (DataXmax + DataXmin) / 2
  219.         Wxmin = xmid - wid / 2
  220.         Wxmax = xmid + wid / 2
  221.     Else
  222.         ' Else see if we're too far to one side.
  223.         If Wxmin < DataXmin And Wxmax < DataXmax Then
  224.             ' Adjust to the right.
  225.             Wxmax = Wxmax + DataXmin - Wxmin
  226.             Wxmin = DataXmin
  227.         End If
  228.         If Wxmax > DataXmax And Wxmin > DataXmin Then
  229.             ' Adjust to the left.
  230.             Wxmin = Wxmin + DataXmax - Wxmax
  231.             Wxmax = DataXmax
  232.         End If
  233.     End If
  234.     If hgt > DataMaxHgt Then
  235.         ' We're taller than the picture. Center.
  236.         ymid = (DataYmax + DataYmin) / 2
  237.         Wymin = ymid - hgt / 2
  238.         Wymax = ymid + hgt / 2
  239.     Else
  240.         ' See if we're too far to top or bottom.
  241.         If Wymin < DataYmin And Wymax < DataYmax Then
  242.             ' Adjust downward.
  243.             Wymax = Wymax + DataYmin - Wymin
  244.             Wymin = DataYmin
  245.         End If
  246.         If Wymax > DataYmax And Wymin > DataYmin Then
  247.             ' Adjust upward.
  248.             Wymin = Wymin + DataYmax - Wymax
  249.             Wymax = DataYmax
  250.         End If
  251.     End If
  252.     ' Map the world window to the viewport.
  253.     Viewport.Scale (Wxmin, Wymax)-(Wxmax, Wymin)
  254.     ' Force the viewport to repaint.
  255.     Viewport.Refresh
  256.         
  257.     ' Reset the scroll bars.
  258.     IgnoreSbarChange = True
  259.     HScrollBar.Visible = (wid < DataXmax - DataXmin)
  260.     VScrollBar.Visible = (hgt < DataYmax - DataYmin)
  261.     ' The values of the scroll bars will be where
  262.     ' the top/left of the world window should be.
  263.     VScrollBar.Min = 100 * (DataYmax)
  264.     VScrollBar.Max = 100 * (DataYmin + hgt)
  265.     HScrollBar.Min = 100 * (DataXmin)
  266.     HScrollBar.Max = 100 * (DataXmax - wid)
  267.     ' SmallChange moves the world window 1/10
  268.     ' of its width/height. Large change moves it
  269.     ' 9/10 of its width/height.
  270.     VScrollBar.SmallChange = 100 * (hgt / 10)
  271.     VScrollBar.LargeChange = 100 * (9 * hgt / 10)
  272.     HScrollBar.SmallChange = 100 * (wid / 10)
  273.     HScrollBar.LargeChange = 100 * (9 * wid / 10)
  274.     ' Set the current scroll bar values.
  275.     VScrollBar.value = 100 * Wymax
  276.     HScrollBar.value = 100 * Wxmin
  277.     IgnoreSbarChange = False
  278. End Sub
  279. ' ************************************************
  280. ' Return to the default magnification scale.
  281. ' ************************************************
  282. Sub SetScaleFull()
  283.     ' Reset the world window coordinates.
  284.     Wxmin = DataXmin
  285.     Wxmax = DataXmax
  286.     Wymin = DataYmin
  287.     Wymax = DataYmax
  288.     ' Set the new world window bounds.
  289.     SetWorldWindow
  290. End Sub
  291. Private Sub Form_Resize()
  292. Const GAP = 40
  293. Dim x As Single
  294. Dim y As Single
  295. Dim wid As Single
  296. Dim hgt As Single
  297.     MakeBoxes
  298.     ' Place the labels and such.
  299.     BoxesLabel.Top = ScaleHeight - BoxesLabel.Height - GAP
  300.     CreatedLabel.Top = BoxesLabel.Top
  301.     Label1(0).Top = BoxesLabel.Top - Label1(0).Height - GAP
  302.     Label1(1).Top = Label1(0).Top
  303.     ' Fit the viewport to the window.
  304.     x = Viewport.Left
  305.     y = Viewport.Top
  306.     wid = ScaleWidth - 2 * x - VScrollBar.Width
  307.     hgt = Label1(0).Top - 2 * y - HScrollBar.Height
  308.     Viewport.Move x, y, wid, hgt
  309.     VAspect = hgt / wid
  310.     ' Place the scroll bars next to the viewport.
  311.     x = Viewport.Left + Viewport.Width + 10
  312.     y = Viewport.Top
  313.     wid = VScrollBar.Width
  314.     hgt = Viewport.Height
  315.     VScrollBar.Move x, y, wid, hgt
  316.     x = Viewport.Left
  317.     y = Viewport.Top + Viewport.Height + 10
  318.     wid = Viewport.Width
  319.     hgt = HScrollBar.Height
  320.     HScrollBar.Move x, y, wid, hgt
  321.     ' Start at full scale.
  322.     SetScaleFull
  323. End Sub
  324. Sub MakeBoxes()
  325. Const NUM_ROWS = 50
  326. Const NUM_COLS = 50
  327. Dim poly As ObjPolygon
  328. Dim i As Integer
  329. Dim j As Integer
  330. Dim x As Single
  331. Dim y As Single
  332. Dim wid As Single
  333. Dim hgt As Single
  334.     MousePointer = vbHourglass
  335.     DoEvents
  336.     ' Compute data bounds.
  337.     wid = 2 * NUM_COLS + 1
  338.     hgt = 2 * NUM_ROWS + 1
  339.     DataXmin = -0.1 * wid   ' 10 % margins.
  340.     DataYmin = -0.1 * hgt
  341.     DataXmax = 1.1 * wid
  342.     DataYmax = 1.1 * hgt
  343.     DataMinWid = 10
  344.     DataMinHgt = 10
  345.     DataMaxWid = DataXmax - DataXmin
  346.     DataMaxHgt = DataYmax - DataYmin
  347.     ' Create the new picture object.
  348.     Set ThePicture = New ObjPicture
  349.     ThePicture.SetBounds DataXmin, DataXmax, DataYmin, DataYmax
  350.     ' Make the boxes.
  351.     y = 0
  352.     For i = 1 To NUM_ROWS
  353.         x = 0
  354.         For j = 1 To NUM_COLS
  355.             Set poly = New ObjPolygon
  356.             poly.NumPoints = 5
  357.             poly.SetPoint 1, x, y
  358.             poly.SetPoint 2, x + 1, y
  359.             poly.SetPoint 3, x + 1, y + 1
  360.             poly.SetPoint 4, x, y + 1
  361.             poly.SetPoint 5, x, y
  362.             ThePicture.Add poly
  363.             x = x + 2
  364.         Next j
  365.         y = y + 2
  366.     Next i
  367.     CreatedLabel.Caption = Format$(NUM_ROWS * NUM_COLS)
  368.     MousePointer = vbDefault
  369. End Sub
  370. ' ************************************************
  371. ' Move the world window.
  372. ' ************************************************
  373. Private Sub HScrollBar_Change()
  374.     If IgnoreSbarChange Then Exit Sub
  375.     HScrollBarChanged
  376. End Sub
  377. ' ************************************************
  378. ' The vertical scroll bar has been moved. Adjust
  379. ' the world window.
  380. ' ************************************************
  381. Sub VScrollBarChanged()
  382. Dim hgt As Single
  383.     hgt = Wymax - Wymin
  384.     Wymax = VScrollBar.value / 100
  385.     Wymin = Wymax - hgt
  386.     ' Remap the world window.
  387.     IgnoreSbarChange = True
  388.     SetWorldWindow
  389.     IgnoreSbarChange = False
  390. End Sub
  391. ' ************************************************
  392. ' The horizontal scroll bar has been moved. Adjust
  393. ' the world window.
  394. ' ************************************************
  395. Sub HScrollBarChanged()
  396. Dim wid As Single
  397.     wid = Wxmax - Wxmin
  398.     Wxmin = HScrollBar.value / 100
  399.     Wxmax = Wxmin + wid
  400.     ' Remap the world window.
  401.     IgnoreSbarChange = True
  402.     SetWorldWindow
  403.     IgnoreSbarChange = False
  404. End Sub
  405. Private Sub mnuFileExit_Click()
  406.     StopZoom    ' If we're zooming, stop it.
  407.     Unload Me
  408. End Sub
  409. ' ************************************************
  410. ' Change the level of magnification.
  411. ' ************************************************
  412. Private Sub mnuScaleMag_Click(Index As Integer)
  413.     StopZoom    ' If we're zooming, stop it.
  414.     If Index = 1 Then
  415.         ' Return to full scale.
  416.         SetScaleFull
  417.     ElseIf Index < 10 Then
  418.         ' Magnify by the indicated amount.
  419.         SetScaleFactor CSng(Index)
  420.     Else
  421.         ' Zoom out by 1/(Index \ 10).
  422.         SetScaleFactor 1 / (Index \ 10)
  423.     End If
  424. End Sub
  425. ' ************************************************
  426. ' Allow the user to select an area to zoom in on.
  427. ' ************************************************
  428. Private Sub mnuScaleZoom_Click()
  429.     ' Enable zooming.
  430.     Viewport.MousePointer = vbCrosshair
  431.     DrawingMode = MODE_START_ZOOM
  432. End Sub
  433. ' ************************************************
  434. ' If we are zooming, start the rubberband box.
  435. ' ************************************************
  436. Private Sub Viewport_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
  437.     Select Case DrawingMode
  438.         Case MODE_START_ZOOM
  439.             ' Start a zooming rubberband box.
  440.             DrawingMode = MODE_ZOOMING
  441.         
  442.             OldMode = Viewport.DrawMode
  443.             Viewport.DrawMode = vbInvert
  444.             
  445.             StartX = x
  446.             StartY = y
  447.             LastX = x
  448.             LastY = y
  449.             Viewport.Line (StartX, StartY)-(LastX, LastY), , B
  450.         
  451.         Case MODE_NONE
  452.             ' Select a box.
  453.             Dim oldcolor As Long
  454.             
  455.             ' Unhighlight the previous box.
  456.             If Not highlighted Is Nothing Then
  457.                 highlighted.Drawn = False
  458.                 highlighted.Draw Viewport
  459.             End If
  460.             
  461.             ' Find the selected box.
  462.             Set highlighted = ThePicture.NearestObject(x, y)
  463.             ' Highlight the selected box.
  464.             If Not highlighted Is Nothing Then
  465.                 oldcolor = Viewport.ForeColor
  466.                 Viewport.ForeColor = RGB(0, 255, 0)
  467.                 highlighted.Drawn = False
  468.                 highlighted.Draw Viewport
  469.                 Viewport.ForeColor = oldcolor
  470.             End If
  471.             
  472.     End Select
  473. End Sub
  474. ' ************************************************
  475. ' If we are zooming, continue the rubberband box.
  476. ' ************************************************
  477. Private Sub Viewport_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
  478.     If DrawingMode <> MODE_ZOOMING Then Exit Sub
  479.     ' Erase the old box.
  480.     Viewport.Line (StartX, StartY)-(LastX, LastY), , B
  481.     ' Draw the new box.
  482.     LastX = x
  483.     LastY = y
  484.     Viewport.Line (StartX, StartY)-(LastX, LastY), , B
  485. End Sub
  486. ' ************************************************
  487. ' If we are zooming, finish the rubberband box.
  488. ' ************************************************
  489. Private Sub Viewport_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
  490. Dim wid As Single
  491. Dim hgt As Single
  492. Dim mid As Single
  493.     If DrawingMode <> MODE_ZOOMING Then Exit Sub
  494.     DrawingMode = MODE_NONE
  495.     ' Erase the old box.
  496.     Viewport.Line (StartX, StartY)-(LastX, LastY), , B
  497.     LastX = x
  498.     LastY = y
  499.     ' We're done drawing for this rubberband box.
  500.     Viewport.DrawMode = OldMode
  501.     Viewport.MousePointer = vbDefault
  502.     ' Set the new world window bounds.
  503.     If StartX > LastX Then
  504.         Wxmin = LastX
  505.         Wxmax = StartX
  506.     Else
  507.         Wxmin = StartX
  508.         Wxmax = LastX
  509.     End If
  510.     If StartY > LastY Then
  511.         Wymin = LastY
  512.         Wymax = StartY
  513.     Else
  514.         Wymin = StartY
  515.         Wymax = LastY
  516.     End If
  517.     ' Set the new world window bounds.
  518.     SetWorldWindow
  519. End Sub
  520. Private Sub Viewport_Paint()
  521. Dim oldcolor As Long
  522.     If ThePicture Is Nothing Then Exit Sub
  523.     MousePointer = vbHourglass
  524.     DoEvents
  525.     NumDraws = 0
  526.     ThePicture.SetDrawn False
  527.     ThePicture.Draw Viewport, Wxmin, Wymin, Wxmax, Wymax
  528.     BoxesLabel.Caption = Format$(NumDraws)
  529.     ' If a box is selected, highlight it.
  530.     If Not highlighted Is Nothing Then
  531.         oldcolor = Viewport.ForeColor
  532.         Viewport.ForeColor = RGB(0, 255, 0)
  533.         highlighted.Drawn = False
  534.         highlighted.Draw Viewport
  535.         Viewport.ForeColor = oldcolor
  536.     End If
  537.     MousePointer = vbDefault
  538. End Sub
  539. ' ************************************************
  540. ' Move the world window.
  541. ' ************************************************
  542. Private Sub VScrollBar_Change()
  543.     If IgnoreSbarChange Then Exit Sub
  544.     VScrollBarChanged
  545. End Sub
  546.